home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
361_02
/
vu.c
< prev
Wrap
Text File
|
1991-09-18
|
16KB
|
466 lines
/* VU --> A File Viewer ala MORE w/ Search & Multi-File/Pipe Lists
*
* J.Ekwall 13 March, 1990
*
* Copyrighted to the Public Domain. Unlimited Distribution Authorized.
*
* User Assumes All Risks/Liabilities.
*
*/
#include <ctype.h>
#include <dos.h>
#include <gadgets.h>
#include <io.h>
#include <keys.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdek.h>
#include <string.h>
char *Documentation[] = {
"",
"Usage:",
" VU [options][drive:][path]filename [, ...] --> View Text Files.",
" | VU [options] ---> View a Text Stream ala MORE.",
"",
"Options:",
" /A -------------> Query for Initial Search.",
" /B -------------> Build/ReBuild Select List.",
" /C0xhhhhhh -----> Specify Colors. [D:/C0x1F301E]",
" /F \"FindMe\" ----> Jump to Text Match.",
" /K -------------> Pop w/ Select List.",
" /R -------------> Respect RamPage UnderLines.",
" /S -------------> CGA Snow Protection.",
"",
" Named Pipes are Legal. Pipes are NOT Errased by Viewing.",
"",
"Last Updated: 18 September 91/EK",
"",
NULL};
char *Pop_Help[] = {
" <ESC> ---------> Exit & View Next File <If Any>.",
" Alt-X ----------> Exit. (Don't View Next File).",
" <Enter> -------> Pop Item Select List. <If Any>",
" ^<Enter> -------> Build/ReBuild a Select List.",
" F2 -----------> Find a Text Phrase.",
"Shift-F2 --------> Find a Text Phrase. Ignore Case.",
" F3 -----------> \"Fuzzy Logic\" Word Finder.",
"Shift-F3 --------> \"Fuzzy Logic\" Word Finder. Ignore Case.",
" F4 -----------> Repeat Search.",
" F5 -----------> Strip Hi-Bit Toggle. [D:don't]",
" F6 -----------> Respect RamPage UnderLines. [D:don't]",
" F8 -----------> Set F3 \"Fuzz\" Level [D: 5]",
" F9 -----------> Select Another File to View",
" F10 ----------> Set/Report Color Settings.",
"",
" <Home> / <Page Up> / <Up Arrow> ----> Roll Upwards.",
" <End> / <Page Down> / <Down Arrow> --> Roll Downward.",
" <Right/Left Arrow> --> Shift Text 10 Spaces.",
"",
" Any Other Key -> Roll Down 11 Lines (Half a Screen).",
NULL};
char *Pop_Help2[] = {
" \"Fuzzy Find\" use the Levenstein Distance Algorithm to",
"compute a \"FuzzFactor\" (how well what you got matches",
"what you wanted):",
"",
" Wanted Have FuzzFactor",
" ────── ──── ──────────",
" FooBar --> FooBar ----> 0",
" FooBar --> fooBar ----> 1",
" FooBar --> FooxBar ---> 1",
" Foo --> FooBar ----> 3",
" Bar --> FooBar ----> 3",
" FooBar --> FooBat ----> 3",
" FooBar --> FooBa -----> 7",
" FooBar --> FoBar -----> 9",
" FooBar --> Foo -------> 20",
"",
" The Value You Set Determines What will be a \"Match\".",
NULL};
/* Declare Constants */
#define LINESIZE 513
/* Declare Globale */
BYTE BarColor = 0x30, NmlColor = 0x1F, HiLite = 0x1E;
int CrashStop = FALSE, WordStar = FALSE, InitAsk = FALSE, InitLst = FALSE;
int Offset = 0, ReBuild = FALSE, Fuzz = 5, RamPage = FALSE, Cleanup = FALSE;
BYTE Find[81], Line[LINESIZE], Name[81], Text[LINESIZE], LastFind[81];
FILE *fp = stdin;
/* Declare Local ProtoTypes */
int AtoHexColors(char **ptr);
int FindLine(int Start, int CaseLess);
int FuzzyFind(char *Have, char *Want);
void GrabStdin(void);
int ItemList(void);
void PaintCRT(int TopLine);
void Show(int CaseLess);
void Usage(void);
void UserSetsColors(void);
main (int argc, char *argv[])
{
int i, xx, yy, Flag = FALSE;
char *tp1, FootPrint[4000];
/* Set Option Flags */
*Find = *LastFind = NULL;
while (*argv[1] IS SLASH) {
for (tp1 = argv[1] + 1; *tp1 != NULL; ) {
switch (toupper(*tp1++)) {
case 'A': InitAsk++; break;
case 'B': ReBuild++; break;
case 'C': /* Colors */
if (!AtoHexColors(&tp1)) Usage(); break;
case 'F':
if (argc IS 2) Usage();
for (i = 1, --argc; i < argc + 1; i++) argv[i] = argv[i+1];
strcpy(Find,argv[1]); strupr(Find); Flag = TRUE;
break;
case 'K': InitLst++; break;
case 'S': CgaSnowFence(); break;
default:
fprintf(stderr,"\nInvalid Option [/%c].\n\n",*tp1);
Usage();
}
}
/* SHIFT */
for (i = 1, --argc; i < argc + 1; i++) argv[i] = argv[i+1];
}
/* Save FootPrint Area */
Getxy(&xx, &yy); SaveBox(1, 1, 80, 25, FootPrint); HideCursor();
/* Determine Ops Mode */
if (argc IS 1) { /* Barefoot Mode */
if (INFLOW_EXISTS) GrabStdin();
if (FileExists("\\STD OUT")) strcpy(Name,"\\STD OUT");
else if (FileExists("\\STD IN")) strcpy(Name,"\\STD IN");
else Usage();
Show(Flag); argc--;
}
/* Show the Specified Files */
for (i = 1; i < argc; i++) {
if (*argv[i] IS '$') {
strcpy(Name,"\\STD "); strcat(Name,++argv[i]);
} else strcpy(Name,argv[i]);
if (FileExists(Name)) Show(Flag);
Flag = FALSE; GetLineN(NULL, 0); if (CrashStop) break;
}
/* Restore FootPrint & Split */
RestoreBox(1, 1, 80, 25, FootPrint); Gotoxy(xx, yy); ShowCursor(0);
if (Cleanup) unlink("\\STD IN"); exit(0);
}
int AtoHexColors(char **ptr)
{
int c, i = 0;
unsigned int n = 0;
if (strncmp(*ptr, "0x", 2) && strncmp(*ptr, "0X", 2)) return FALSE;
for (*ptr += 2; isxdigit(c = toupper(**ptr)) && i++ < 6; *ptr += 1) {
n = (isdigit(c)) ? 16 * n + c - 48 : 16 * n + c - 55;
if (i IS 2) { NmlColor = n; n = 0; }
if (i IS 4) { BarColor = n; n = 0; }
if (i IS 6) HiLite = n;
}
return (i >= 6);
}
int FindLine(int Start, int CaseLess)
{
int i, Dits = 18;
char *tp1, DitLine[81];
if (!*Find) return(Start); strcpy(DitLine, "---<Scanning>--- ");
strcpy(LastFind, Find);
for (i = Start; GetLineN(Line, (++i) + 1); ) {
if (WordStar) for (tp1 = Line; *tp1 != NULL; ) *tp1++ &= 127;
if (CaseLess % 2) strupr(Line);
if (CaseLess < 2) { if(strstr(Line, Find) != NULL) return(i); }
else for (tp1 = strtok(Line, " \t\n"); *tp1;
tp1 = strtok(NULL, " \t\n")) if (FuzzyFind(tp1, Find) < Fuzz)
return(i);
if (i % 23) continue;
if (++Dits IS 78) {
strcpy(DitLine,"."); Dits = 1;
} else strcat(DitLine, ".");
DwriteEnd(1, 25, BarColor, DitLine, 80);
if (Kbq_poll() IS SPACE) break;
}
putchar(BEL); return(Start);
}
int FuzzyFind(char *Have, char *Want)
{
int i, j, Delta, Prev, Distance[21];
char Text[21], String[21], *tp1, *tp2;
strncpy(Text, Want, 20); strncpy(String, Have, 20);
Text[21] = String[21] = NULL; if (!*Want) return 0;
if (!*Have) return 5 * strlen(Want);
for (i = 0; i < 21; i++) Distance[i] = i;
tp1 = Text;
do {
Prev = Distance[0] + 5; tp2 = String; i = 0;
do {
Delta = Prev + 1;
if (*tp1 == *tp2) j = 0;
else if (toupper(*tp1) == toupper(*tp2)) j = 1;
else j = 3;
if ((j += Distance[i]) < Delta) Delta = j; Distance[i] = Prev;
if ((j = Distance[++i] + 5) < Delta) Delta = j; Prev = Delta;
} while (*tp2++);
Distance[strlen(String)] = Delta;
} while (*tp1++);
if ((j = strlen(Text) - strlen(String)) > 0) Delta += 4 * j;
return --Delta;
}
void GrabStdin(void)
{
int c;
if ((fp = fopen("\\STD IN", "w")) IS NULL) Usage();
while((c = getchar()) != EOF) fputc(c, fp);
fclose(fp); Cleanup++;
}
int ItemList(void)
{
/* Find/Read .LST File, Present List(s) & Post User Selection */
int i, Flag, TopItem, NxtLine, X, Y, xx, yy;
char ListName[81], *tp1;
/* Find .LST File */
strupr(Name); if (strstr(Name, ".TXT") IS NULL) return FALSE;
NewExt(Name, ListName, "LST");